package com.m1.tzolkin.model.util.zone;

import java.io.Serializable;
import java.util.Collection;

import com.m1.tzolkin.model.exceptions.StepMoveException;

/**
 * Une zone dans laquelle des �l�ments peuvent �voluer.
 * 
 * @inv <pre>
 *     getStepsNb() > 0 </pre>
 *     
 * @cons <pre>
 * $DESC$
 *     Une zone parcourable avec n marches.
 * $ARGS$
 *     int n
 * $PRE$
 *     n > 0
 * $POST$
 *     getPlayers().isEmpty()
 *     getStepsNb() == n </pre>
 *
 */
public interface IStepsZone<P> extends Serializable {
	
	// REQUETES
	
	/**
	 * Retourne les cl�s pr�sentes dans cette zone.
	 */
	Collection<P> getKeys();
	
	/**
	 * Retourne le niveau de l'�l�ment p.
	 * Retourne null si p n'est pas dans cette zone.
	 * @pre <pre>
	 *     p != null </pre>
	 */
	Integer getStep(P p);
	
	/**
	 * Retourne le nombre de marches de cette zone.
	 */
	int getStepsNb();
	
	// COMMANDES
	
	/**
	 * Ajoute la cl� p � cette zone.
	 * N'a aucun effet si p est d�j� dans cette zone.
	 * @pre <pre>
	 *     p != null </pre>
	 * @post <pre>
	 *     getKeys().contains(p)
	 *     getStep(p) == 0 </pre>
	 */
	void addKey(P p);
	
	/**
	 * Ajoute la cl� p � cette zone � la marche i.
	 * N'a aucun effet si p est d�j� dans cette zone.
	 * @pre <pre>
	 *     p != null
	 *     0 <= i < getStepsNb() </pre>
	 * @post <pre>
	 *     getKeys().contains(p)
	 *     getStep(p) == i </pre>
	 */
	void addKey(P p, int i);
	
	/**
	 * Monte d'une marche l'�l�ment p.
	 * L�ve une StepMoveException si p est d�j� sur la derni�re marche de z.
	 * @pre <pre>
	 *     p != null
	 *     getKeys().contains(p)
	 *     getStep(p) < getStepsNb() - 1 </pre>
	 * @post <pre>
	 *     getStep(p) == old getStep(p) + 1 </pre>
	 */
	void up(P p) throws StepMoveException;
	
	/**
	 * Descend d'une marche l'�l�ment p.
	 * L�ve une StepMoveException si p est d�j� sur la premi�re marche de z.
	 * @pre <pre>
	 *     p != null
	 *     getKeys().contains(p)
	 *     getStep(p) > 0 </pre>
	 * @post <pre>
	 *     getStep(p) == old getStep(p) - 1 </pre>
	 */
	void down(P p) throws StepMoveException;

}
